<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>详解JDK8新特性 | 风祈的时光录</title><meta name="keywords" content="Java8，新特性，JDK8"><meta name="author" content="youthlql"><meta name="copyright" content="youthlql"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="详解JDK8出现的新特性。">
<meta property="og:type" content="article">
<meta property="og:title" content="详解JDK8新特性">
<meta property="og:url" content="https://imlql.cn/post/de3879ae.html">
<meta property="og:site_name" content="风祈的时光录">
<meta property="og:description" content="详解JDK8出现的新特性。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://upyunimg.imlql.cn/lql_static@latest/logo/java.png">
<meta property="article:published_time" content="2020-10-19T14:15:58.000Z">
<meta property="article:modified_time" content="2022-07-24T11:02:09.866Z">
<meta property="article:author" content="youthlql">
<meta property="article:tag" content="Java8">
<meta property="article:tag" content="JDK8">
<meta property="article:tag" content="新特性">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://upyunimg.imlql.cn/lql_static@latest/logo/java.png"><link rel="shortcut icon" href="https://npm.elemecdn.com/youthlql@1.0.8/blog/favicon.png"><link rel="canonical" href="https://imlql.cn/post/de3879ae"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://npm.elemecdn.com/@fortawesome/fontawesome-free@6/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/@fancyapps/ui/dist/fancybox.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?f693ff99cc7e613b88cf5b729a14b48b";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '详解JDK8新特性',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-07-24 19:02:09'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="https://npm.elemecdn.com/lql_static@latest/butterfly_static/css/ali_icon.css"><link rel="stylesheet" href="https://npm.elemecdn.com/lql_static@latest/butterfly_static/css/2-24-mogai.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="风祈的时光录" type="application/atom+xml">
</head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/avatar/2.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data is-center"><div class="data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">37</div></a></div><div class="data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">21</div></a></div><div class="data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">13</div></a></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 找文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/categories/"><i class="fa-fw iconfont icon-fenlei1"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw iconfont icon-biaoqian1"></i><span> 标签</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw iconfont icon-shijianzhou"></i><span> 归档</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://upyunimg.imlql.cn/lql_static@latest/logo/java.png')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">风祈的时光录</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 找文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/categories/"><i class="fa-fw iconfont icon-fenlei1"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw iconfont icon-biaoqian1"></i><span> 标签</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw iconfont icon-shijianzhou"></i><span> 归档</span></a></li></ul></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">详解JDK8新特性</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-10-19T14:15:58.000Z" title="发表于 2020-10-19 22:15:58">2020-10-19</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-07-24T11:02:09.866Z" title="更新于 2022-07-24 19:02:09">2022-07-24</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java%E5%9F%BA%E7%A1%80/">Java基础</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java%E5%9F%BA%E7%A1%80/%E6%96%B0%E7%89%B9%E6%80%A7/">新特性</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">7.9k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>34分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="Java8新特性纵览"><a href="#Java8新特性纵览" class="headerlink" title="Java8新特性纵览"></a>Java8新特性纵览</h1><blockquote>
<p>本篇文章只讲解比较重要的</p>
</blockquote>
<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.8/Java_Basis/Java8_New_Features/0001.png">



<h1 id="Lambda表达式"><a href="#Lambda表达式" class="headerlink" title="Lambda表达式"></a>Lambda表达式</h1><h2 id="为什么使用Lambda表达式？"><a href="#为什么使用Lambda表达式？" class="headerlink" title="为什么使用Lambda表达式？"></a>为什么使用Lambda表达式？</h2><ul>
<li>Lambda 是一个<strong>匿名函数</strong>，我们可以把 Lambda 表达式理解为是<strong>一段可以传递的代码</strong>（将代码像数据一样进行传递）。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格，使Java的语言表达能力得到了提升。</li>
<li>在Java8之后的很多源码里用到了Lambda表达式，不学的话可能看不懂源码。</li>
</ul>
<h2 id="简单使用"><a href="#简单使用" class="headerlink" title="简单使用"></a>简单使用</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line">       <span class="comment">//原始写法</span></span><br><span class="line">       Runnable r1 = <span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">           <span class="meta">@Override</span></span><br><span class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">               System.out.println(<span class="string">&quot;我爱北京天安门&quot;</span>);</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;;</span><br><span class="line"></span><br><span class="line">       r1.run();</span><br><span class="line"></span><br><span class="line">       System.out.println(<span class="string">&quot;***********************&quot;</span>);</span><br><span class="line"></span><br><span class="line">       <span class="comment">//lambda表达式，可以表达一样的意思</span></span><br><span class="line">       Runnable r2 = () -&gt; System.out.println(<span class="string">&quot;我爱北京故宫&quot;</span>);</span><br><span class="line"></span><br><span class="line">       r2.run();</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">   <span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">       Comparator&lt;Integer&gt; com1 = <span class="keyword">new</span> Comparator&lt;Integer&gt;() &#123;</span><br><span class="line">           <span class="meta">@Override</span></span><br><span class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(Integer o1, Integer o2)</span> </span>&#123;</span><br><span class="line">               <span class="keyword">return</span> Integer.compare(o1,o2);</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;;</span><br><span class="line"></span><br><span class="line">       <span class="keyword">int</span> compare1 = com1.compare(<span class="number">12</span>,<span class="number">21</span>);</span><br><span class="line">       System.out.println(compare1);</span><br><span class="line"></span><br><span class="line">       System.out.println(<span class="string">&quot;***********************&quot;</span>);</span><br><span class="line">       </span><br><span class="line">       <span class="comment">//Lambda表达式的写法</span></span><br><span class="line">       Comparator&lt;Integer&gt; com2 = (o1,o2) -&gt; Integer.compare(o1,o2);</span><br><span class="line"></span><br><span class="line">       <span class="keyword">int</span> compare2 = com2.compare(<span class="number">32</span>,<span class="number">21</span>);</span><br><span class="line">       System.out.println(compare2);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">       System.out.println(<span class="string">&quot;***********************&quot;</span>);</span><br><span class="line">       <span class="comment">//方法引用</span></span><br><span class="line">       Comparator&lt;Integer&gt; com3 = Integer :: compare;</span><br><span class="line"></span><br><span class="line">       <span class="keyword">int</span> compare3 = com3.compare(<span class="number">32</span>,<span class="number">21</span>);</span><br><span class="line">       System.out.println(compare3);</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>



<h2 id="Lambda语法规则"><a href="#Lambda语法规则" class="headerlink" title="Lambda语法规则"></a>Lambda语法规则</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.Comparator;</span><br><span class="line"><span class="keyword">import</span> java.util.function.Consumer;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Lambda表达式的使用</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 1.举例： (o1,o2) -&gt; Integer.compare(o1,o2);</span></span><br><span class="line"><span class="comment"> * 2.格式：</span></span><br><span class="line"><span class="comment"> * -&gt; :lambda操作符 或 箭头操作符</span></span><br><span class="line"><span class="comment"> * -&gt;左边：lambda形参列表 （其实就是接口中的抽象方法的形参列表）</span></span><br><span class="line"><span class="comment"> * -&gt;右边：lambda体 （其实就是重写的抽象方法的方法体）</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 3. Lambda表达式的使用：（分为6种情况介绍）</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 总结：</span></span><br><span class="line"><span class="comment"> * -&gt;左边：lambda形参列表的参数类型可以省略(类型推断)；如果lambda形参列表只有一个参数，其一对()也</span></span><br><span class="line"><span class="comment"> * 可以省略</span></span><br><span class="line"><span class="comment"> * -&gt;右边：lambda体应该使用一对&#123;&#125;包裹；如果lambda体只有一条执行语句（可能是return语句），省略这一</span></span><br><span class="line"><span class="comment"> 对&#123;&#125;和return关键字</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 4.Lambda表达式的本质：作为函数式接口的实例</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 5. 如果一个接口中，只声明了一个抽象方法，则此接口就称为函数式接口。我们可以在一个接口上</span></span><br><span class="line"><span class="comment"> 使用 <span class="doctag">@FunctionalInterface</span> 注解，</span></span><br><span class="line"><span class="comment"> * 这样做可以检查它是否是一个函数式接口。</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 6. 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LambdaTest1</span> </span>&#123;</span><br><span class="line">    <span class="comment">//语法格式一：无参，无返回值</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Runnable r1 = <span class="keyword">new</span> Runnable() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;我爱北京天安门&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        r1.run();</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;***********************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Runnable r2 = () -&gt; &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;我爱北京故宫&quot;</span>);</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        r2.run();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//语法格式二：Lambda 需要一个参数，但是没有返回值。</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        Consumer&lt;String&gt; con = <span class="keyword">new</span> Consumer&lt;String&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line">                System.out.println(s);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        con.accept(<span class="string">&quot;谎言和誓言的区别是什么？&quot;</span>);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Consumer&lt;String&gt; con1 = (String s) -&gt; &#123;</span><br><span class="line">            System.out.println(s);</span><br><span class="line">        &#125;;</span><br><span class="line">        con1.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//语法格式三：数据类型可以省略，因为可由编译器推断得出，称为“类型推断”</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        Consumer&lt;String&gt; con1 = (String s) -&gt; &#123;</span><br><span class="line">            System.out.println(s);</span><br><span class="line">        &#125;;</span><br><span class="line">        con1.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Consumer&lt;String&gt; con2 = (s) -&gt; &#123;</span><br><span class="line">            System.out.println(s);</span><br><span class="line">        &#125;;</span><br><span class="line">        con2.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        ArrayList&lt;String&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();<span class="comment">//类型推断</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">int</span>[] arr = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;;<span class="comment">//类型推断</span></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//语法格式四：Lambda 若只需要一个参数时，参数的小括号可以省略</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test5</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Consumer&lt;String&gt; con1 = (s) -&gt; &#123;</span><br><span class="line">            System.out.println(s);</span><br><span class="line">        &#125;;</span><br><span class="line">        con1.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Consumer&lt;String&gt; con2 = s -&gt; &#123;</span><br><span class="line">            System.out.println(s);</span><br><span class="line">        &#125;;</span><br><span class="line">        con2.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//语法格式五：Lambda 需要两个或以上的参数，多条执行语句，并且可以有返回值</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test6</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        Comparator&lt;Integer&gt; com1 = <span class="keyword">new</span> Comparator&lt;Integer&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(Integer o1, Integer o2)</span> </span>&#123;</span><br><span class="line">                System.out.println(o1);</span><br><span class="line">                System.out.println(o2);</span><br><span class="line">                <span class="keyword">return</span> o1.compareTo(o2);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        System.out.println(com1.compare(<span class="number">12</span>, <span class="number">21</span>));</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*****************************&quot;</span>);</span><br><span class="line">        Comparator&lt;Integer&gt; com2 = (o1, o2) -&gt; &#123;</span><br><span class="line">            System.out.println(o1);</span><br><span class="line">            System.out.println(o2);</span><br><span class="line">            <span class="keyword">return</span> o1.compareTo(o2);</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        System.out.println(com2.compare(<span class="number">12</span>, <span class="number">6</span>));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//语法格式六：当 Lambda 体只有一条语句时，return 与大括号若有，都可以省略</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test7</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        Comparator&lt;Integer&gt; com1 = (o1, o2) -&gt; &#123;</span><br><span class="line">            <span class="keyword">return</span> o1.compareTo(o2);</span><br><span class="line">        &#125;;</span><br><span class="line"></span><br><span class="line">        System.out.println(com1.compare(<span class="number">12</span>, <span class="number">6</span>));</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*****************************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Comparator&lt;Integer&gt; com2 = (o1, o2) -&gt; o1.compareTo(o2);</span><br><span class="line"></span><br><span class="line">        System.out.println(com2.compare(<span class="number">12</span>, <span class="number">21</span>));</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test8</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Consumer&lt;String&gt; con1 = s -&gt; &#123;</span><br><span class="line">            System.out.println(s);</span><br><span class="line">        &#125;;</span><br><span class="line">        con1.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*****************************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Consumer&lt;String&gt; con2 = s -&gt; System.out.println(s);</span><br><span class="line"></span><br><span class="line">        con2.accept(<span class="string">&quot;一个是听得人当真了，一个是说的人当真了&quot;</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h1 id="函数式接口"><a href="#函数式接口" class="headerlink" title="函数式接口"></a>函数式接口</h1><h2 id="什么是函数式-Functional-接口"><a href="#什么是函数式-Functional-接口" class="headerlink" title="什么是函数式(Functional)接口"></a>什么是函数式(Functional)接口</h2><ul>
<li><p>只包含一个抽象方法的接口，称为<strong>函数式接口</strong>。 </p>
</li>
<li><p>你可以通过 Lambda 表达式来创建该接口的对象。（若 Lambda 表达式抛出一个受检异常(即：非运行时异常)，那么该异常需要在目标接口的抽象方法上进行声明）。</p>
</li>
<li><p>我们可以在一个接口上使用 <strong>@FunctionalInterface</strong> 注解，这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明，说明这个接口是一个函数式接口。</p>
</li>
<li><p>在java.util.function包下定义了Java 8 的丰富的函数式接口</p>
</li>
</ul>
<h2 id="如何理解函数式接口"><a href="#如何理解函数式接口" class="headerlink" title="如何理解函数式接口"></a>如何理解函数式接口</h2><ul>
<li>Java从诞生日起就是一直倡导“一切皆对象”，在Java里面面向对象(OOP)编程是一切。但是随着python、scala等语言的兴起和新技术的挑战，Java不得不做出调整以便支持更加广泛的技术要求，也即java不但可以支持OOP还可以支持OOF（面向函数编程） </li>
<li>在函数式编程语言当中，函数被当做一等公民对待。在将函数作为一等公民的编程语言中，Lambda表达式的类型是函数。但是在Java8中，有所不同。在Java8中，Lambda表达式是对象，而不是函数，它们必须依附于一类特别的对象类型——函数式接口。 </li>
<li>简单的说，在Java8中，Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说，只要一个对象是函数式接口的实例，那么该对象就可以用Lambda表达式来表示。</li>
<li>所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。</li>
</ul>
<h2 id="Java内置函数式接口"><a href="#Java内置函数式接口" class="headerlink" title="Java内置函数式接口"></a>Java内置函数式接口</h2><p><strong>核心函数式接口</strong></p>
<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.8/Java_Basis/Java8_New_Features/0002.png">



<p><strong>其它函数式接口</strong></p>
<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.8/Java_Basis/Java8_New_Features/0003.png">





<p><strong>Consumer</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">       happyTime(<span class="number">500</span>, <span class="keyword">new</span> Consumer&lt;Double&gt;() &#123;</span><br><span class="line">           <span class="meta">@Override</span></span><br><span class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(Double aDouble)</span> </span>&#123;</span><br><span class="line">               System.out.println(<span class="string">&quot;学习太累了，去天上人间买了瓶矿泉水，价格为：&quot;</span> + aDouble);</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;);</span><br><span class="line"></span><br><span class="line">       System.out.println(<span class="string">&quot;********************&quot;</span>);</span><br><span class="line"></span><br><span class="line">       happyTime(<span class="number">400</span>,money -&gt; System.out.println(<span class="string">&quot;学习太累了，去天上人间喝了口水，价格为：&quot;</span> + money));</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">happyTime</span><span class="params">(<span class="keyword">double</span> money, Consumer&lt;Double&gt; con)</span></span>&#123;</span><br><span class="line">       con.accept(money);</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>



<p><strong>结果：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">学习太累了，去天上人间买了瓶矿泉水，价格为：<span class="number">500.0</span></span><br><span class="line">********************</span><br><span class="line">学习太累了，去天上人间喝了口水，价格为：<span class="number">400.0</span></span><br><span class="line"></span><br><span class="line">Process finished with exit code <span class="number">0</span></span><br></pre></td></tr></table></figure>



<p><strong>Predicate</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;北京&quot;</span>,<span class="string">&quot;南京&quot;</span>,<span class="string">&quot;天津&quot;</span>,<span class="string">&quot;东京&quot;</span>,<span class="string">&quot;西京&quot;</span>,<span class="string">&quot;普京&quot;</span>);</span><br><span class="line"></span><br><span class="line">        List&lt;String&gt; filterStrs = filterString(list, <span class="keyword">new</span> Predicate&lt;String&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">test</span><span class="params">(String s)</span> </span>&#123;<span class="comment">//这里是定义一个校验规则</span></span><br><span class="line">                <span class="keyword">return</span> s.contains(<span class="string">&quot;京&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        System.out.println(filterStrs);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//用lambda表达式会很简单</span></span><br><span class="line">        List&lt;String&gt; filterStrs1 = filterString(list,s -&gt; s.contains(<span class="string">&quot;京&quot;</span>));</span><br><span class="line">        System.out.println(filterStrs1);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//根据给定的规则，过滤集合中的字符串。此规则由Predicate的方法决定</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">filterString</span><span class="params">(List&lt;String&gt; list, Predicate&lt;String&gt; pre)</span></span>&#123;</span><br><span class="line"></span><br><span class="line">        ArrayList&lt;String&gt; filterList = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span>(String s : list)&#123;</span><br><span class="line">            <span class="keyword">if</span>(pre.test(s))&#123;</span><br><span class="line">                filterList.add(s);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> filterList;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<p><strong>结果：</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">[北京, 南京, 东京, 西京, 普京]</span><br><span class="line">[北京, 南京, 东京, 西京, 普京]</span><br><span class="line"></span><br><span class="line">Process finished with exit code 0</span><br></pre></td></tr></table></figure>



<h2 id="自定义函数式接口"><a href="#自定义函数式接口" class="headerlink" title="自定义函数式接口"></a>自定义函数式接口</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 自定义函数式接口</span></span><br><span class="line"><span class="comment"> * 只是说加上<span class="doctag">@FunctionalInterface</span>之后可以校验</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@FunctionalInterface</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">MyFunInterface</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getValue</span><span class="params">(T t)</span></span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//这个方法的第一个参数是lambda表达式，相当于是实例化了那个函数式接口</span></span><br><span class="line">        String s = toUpperString(str -&gt; str.toUpperCase(), <span class="string">&quot;abcd&quot;</span>);</span><br><span class="line">        System.out.println(s);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">toUpperString</span><span class="params">(MyFunInterface&lt;String&gt; mf,String str)</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> mf.getValue(str);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h1 id="方法引用"><a href="#方法引用" class="headerlink" title="方法引用"></a>方法引用</h1><ul>
<li><p>当要传递给Lambda体的操作，已经有实现的方法了，可以使用方法引用！</p>
</li>
<li><p>方法引用可以看做是Lambda表达式深层次的表达。换句话说，方法引用就是Lambda表达式，也就是函数式接口的一个实例，通过方法的名字来指向一个方法，可以认为是Lambda表达式的一个语法糖。</p>
</li>
<li><p>要求：实现接口的抽象方法的参数列表和返回值类型，必须与方法引用的方法的参数列表和返回值类型保持一致！</p>
</li>
<li><p>格式：使用操作符 “::” 将类(或对象) 与 方法名分隔开来。</p>
</li>
<li><p>如下三种主要使用情况： </p>
<ul>
<li><p>对象 :: 实例方法名</p>
</li>
<li><p>类 :: 静态方法名</p>
</li>
<li><p>类 :: 实例方法名</p>
</li>
</ul>
</li>
</ul>
<p>我们直接拿例子来说明情况，先提前准备两个类：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Employee</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">int</span> id;</span><br><span class="line">	<span class="keyword">private</span> String name;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">int</span> age;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">double</span> salary;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getId</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> id;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setId</span><span class="params">(<span class="keyword">int</span> id)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.id = id;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> name;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.name = name;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getAge</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> age;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(<span class="keyword">int</span> age)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.age = age;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">getSalary</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> salary;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setSalary</span><span class="params">(<span class="keyword">double</span> salary)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.salary = salary;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">&quot;Employee().....&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(<span class="keyword">int</span> id)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.id = id;</span><br><span class="line">		System.out.println(<span class="string">&quot;Employee(int id).....&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(<span class="keyword">int</span> id, String name)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.id = id;</span><br><span class="line">		<span class="keyword">this</span>.name = name;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(<span class="keyword">int</span> id, String name, <span class="keyword">int</span> age, <span class="keyword">double</span> salary)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">		<span class="keyword">this</span>.id = id;</span><br><span class="line">		<span class="keyword">this</span>.name = name;</span><br><span class="line">		<span class="keyword">this</span>.age = age;</span><br><span class="line">		<span class="keyword">this</span>.salary = salary;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="string">&quot;Employee&#123;&quot;</span> + <span class="string">&quot;id=&quot;</span> + id + <span class="string">&quot;, name=&#x27;&quot;</span> + name + <span class="string">&#x27;\&#x27;&#x27;</span> + <span class="string">&quot;, age=&quot;</span> + age + <span class="string">&quot;, salary=&quot;</span> + salary + <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object o)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (<span class="keyword">this</span> == o)</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">		<span class="keyword">if</span> (o == <span class="keyword">null</span> || getClass() != o.getClass())</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line">		Employee employee = (Employee) o;</span><br><span class="line"></span><br><span class="line">		<span class="keyword">if</span> (id != employee.id)</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		<span class="keyword">if</span> (age != employee.age)</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		<span class="keyword">if</span> (Double.compare(employee.salary, salary) != <span class="number">0</span>)</span><br><span class="line">			<span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">		<span class="keyword">return</span> name != <span class="keyword">null</span> ? name.equals(employee.name) : employee.name == <span class="keyword">null</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hashCode</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">int</span> result;</span><br><span class="line">		<span class="keyword">long</span> temp;</span><br><span class="line">		result = id;</span><br><span class="line">		result = <span class="number">31</span> * result + (name != <span class="keyword">null</span> ? name.hashCode() : <span class="number">0</span>);</span><br><span class="line">		result = <span class="number">31</span> * result + age;</span><br><span class="line">		temp = Double.doubleToLongBits(salary);</span><br><span class="line">		result = <span class="number">31</span> * result + (<span class="keyword">int</span>) (temp ^ (temp &gt;&gt;&gt; <span class="number">32</span>));</span><br><span class="line">		<span class="keyword">return</span> result;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 提供用于测试的数据</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EmployeeData</span> </span>&#123;</span><br><span class="line">   </span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> List&lt;Employee&gt; <span class="title">getEmployees</span><span class="params">()</span></span>&#123;</span><br><span class="line">      List&lt;Employee&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">      </span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1001</span>, <span class="string">&quot;马化腾&quot;</span>, <span class="number">34</span>, <span class="number">6000.38</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1002</span>, <span class="string">&quot;马云&quot;</span>, <span class="number">12</span>, <span class="number">9876.12</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1003</span>, <span class="string">&quot;刘强东&quot;</span>, <span class="number">33</span>, <span class="number">3000.82</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1004</span>, <span class="string">&quot;雷军&quot;</span>, <span class="number">26</span>, <span class="number">7657.37</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1005</span>, <span class="string">&quot;李彦宏&quot;</span>, <span class="number">65</span>, <span class="number">5555.32</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1006</span>, <span class="string">&quot;比尔盖茨&quot;</span>, <span class="number">42</span>, <span class="number">9500.43</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1007</span>, <span class="string">&quot;任正非&quot;</span>, <span class="number">26</span>, <span class="number">4333.32</span>));</span><br><span class="line">      list.add(<span class="keyword">new</span> Employee(<span class="number">1008</span>, <span class="string">&quot;扎克伯格&quot;</span>, <span class="number">35</span>, <span class="number">2500.32</span>));</span><br><span class="line">      </span><br><span class="line">      <span class="keyword">return</span> list;</span><br><span class="line">   &#125;</span><br><span class="line">   </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p><strong>下面来通过实际例子讲解方法引用：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 方法引用的使用</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 1.使用情境：当要传递给Lambda体的操作，已经有实现的方法了，可以使用方法引用！</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 2.方法引用，本质上就是Lambda表达式，而Lambda表达式作为函数式接口的实例。所以</span></span><br><span class="line"><span class="comment"> *   方法引用，也是函数式接口的实例。</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 3. 使用格式：  类(或对象) :: 方法名</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 4. 具体分为如下的三种情况：</span></span><br><span class="line"><span class="comment"> *    情况1     对象 :: 非静态方法</span></span><br><span class="line"><span class="comment"> *    情况2     类 :: 静态方法</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *    情况3     类 :: 非静态方法</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 5. 方法引用使用的要求：</span></span><br><span class="line"><span class="comment"> * 	接口中的抽象方法的形参列表和返回值类型</span></span><br><span class="line"><span class="comment"> * 	与</span></span><br><span class="line"><span class="comment"> * 	方法引用的方法的形参列表和返回值类型相同！（针对于情况1和情况2）</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MethodRefTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 情况一：对象 :: 实例方法</span></span><br><span class="line">	<span class="comment">//Consumer中的void accept(T t)</span></span><br><span class="line">	<span class="comment">//PrintStream中的void println(T t)</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Consumer&lt;String&gt; con1 = str -&gt; System.out.println(str);</span><br><span class="line">		con1.accept(<span class="string">&quot;北京&quot;</span>);</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line">		PrintStream ps = System.out;</span><br><span class="line">		Consumer&lt;String&gt; con2 = ps::println;</span><br><span class="line">		con2.accept(<span class="string">&quot;beijing&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="comment">//Supplier中的T get()</span></span><br><span class="line">	<span class="comment">//Employee中的String getName()</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Employee emp = <span class="keyword">new</span> Employee(<span class="number">1001</span>,<span class="string">&quot;Tom&quot;</span>,<span class="number">23</span>,<span class="number">5600</span>);</span><br><span class="line"></span><br><span class="line">		Supplier&lt;String&gt; sup1 = () -&gt; emp.getName();</span><br><span class="line">		System.out.println(sup1.get());</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line">		Supplier&lt;String&gt; sup2 = emp::getName;</span><br><span class="line">		System.out.println(sup2.get());</span><br><span class="line"></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 情况二：类 :: 静态方法</span></span><br><span class="line">	<span class="comment">//Comparator中的int compare(T t1,T t2)</span></span><br><span class="line">	<span class="comment">//Integer中的int compare(T t1,T t2)</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Comparator&lt;Integer&gt; com1 = (t1,t2) -&gt; Integer.compare(t1,t2);</span><br><span class="line">		System.out.println(com1.compare(<span class="number">12</span>,<span class="number">21</span>));</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">		Comparator&lt;Integer&gt; com2 = Integer::compare;</span><br><span class="line">		System.out.println(com2.compare(<span class="number">12</span>,<span class="number">3</span>));</span><br><span class="line"></span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="comment">//Function中的R apply(T t)</span></span><br><span class="line">	<span class="comment">//Math中的Long round(Double d)</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Function&lt;Double,Long&gt; func = <span class="keyword">new</span> Function&lt;Double, Long&gt;() &#123;</span><br><span class="line">			<span class="meta">@Override</span></span><br><span class="line">			<span class="function"><span class="keyword">public</span> Long <span class="title">apply</span><span class="params">(Double d)</span> </span>&#123;</span><br><span class="line">				<span class="keyword">return</span> Math.round(d);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;;</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">		Function&lt;Double,Long&gt; func1 = d -&gt; Math.round(d);</span><br><span class="line">		System.out.println(func1.apply(<span class="number">12.3</span>));</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">		Function&lt;Double,Long&gt; func2 = Math::round;</span><br><span class="line">		System.out.println(func2.apply(<span class="number">12.6</span>));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 情况三：类 :: 实例方法  (有难度)</span></span><br><span class="line">	<span class="comment">// Comparator中的int comapre(T t1,T t2)  第一个参数T t1,也可以变成方法的调用者</span></span><br><span class="line">	<span class="comment">// String中的int t1.compareTo(t2)        看上面说的，t1变成了调用者等价于第一个参数T t1</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test5</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Comparator&lt;String&gt; com1 = (s1,s2) -&gt; s1.compareTo(s2);</span><br><span class="line">		System.out.println(com1.compare(<span class="string">&quot;abc&quot;</span>,<span class="string">&quot;abd&quot;</span>));</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">		Comparator&lt;String&gt; com2 = String :: compareTo;</span><br><span class="line">		System.out.println(com2.compare(<span class="string">&quot;abd&quot;</span>,<span class="string">&quot;abm&quot;</span>));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//BiPredicate中的boolean test(T t1, T t2);</span></span><br><span class="line">	<span class="comment">//String中的boolean t1.equals(t2)</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test6</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		BiPredicate&lt;String,String&gt; pre1 = (s1,s2) -&gt; s1.equals(s2);</span><br><span class="line">		System.out.println(pre1.test(<span class="string">&quot;abc&quot;</span>,<span class="string">&quot;abc&quot;</span>));</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line">		BiPredicate&lt;String,String&gt; pre2 = String :: equals;</span><br><span class="line">		System.out.println(pre2.test(<span class="string">&quot;abc&quot;</span>,<span class="string">&quot;abd&quot;</span>));</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="comment">// Function中的R apply(T t)</span></span><br><span class="line">	<span class="comment">// Employee中的String getName();   第一个参数T t相当于方法调用者emp，返回值R和String对应</span></span><br><span class="line">	<span class="meta">@Test</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test7</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		Employee employee = <span class="keyword">new</span> Employee(<span class="number">1001</span>, <span class="string">&quot;Jerry&quot;</span>, <span class="number">23</span>, <span class="number">6000</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">		Function&lt;Employee,String&gt; func1 = e -&gt; e.getName();</span><br><span class="line">		System.out.println(func1.apply(employee));</span><br><span class="line"></span><br><span class="line">		System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">		Function&lt;Employee,String&gt; func2 = Employee::getName;</span><br><span class="line">		System.out.println(func2.apply(employee));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>





<h1 id="构造器引用"><a href="#构造器引用" class="headerlink" title="构造器引用"></a>构造器引用</h1><p>格式：ClassName :: new</p>
<p>与函数式接口相结合，自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法，要求构造器参数列表要与接口中抽象方法的参数列表一致！且方法的返回值即为构造器对应类的对象。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Arrays;</span><br><span class="line"><span class="keyword">import</span> java.util.function.BiFunction;</span><br><span class="line"><span class="keyword">import</span> java.util.function.Function;</span><br><span class="line"><span class="keyword">import</span> java.util.function.Supplier;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 一、构造器引用</span></span><br><span class="line"><span class="comment"> *      和方法引用类似，函数式接口的抽象方法的形参列表和构造器的形参列表一致。</span></span><br><span class="line"><span class="comment"> *      抽象方法的返回值类型即为构造器所属的类的类型</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 二、数组引用</span></span><br><span class="line"><span class="comment"> *     大家可以把数组看做是一个特殊的类，则写法与构造器引用一致。</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConstructorRefTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 构造器引用</span></span><br><span class="line"><span class="comment">     * Supplier中的T get()</span></span><br><span class="line"><span class="comment">     * Employee的空参构造器：Employee()</span></span><br><span class="line"><span class="comment">     * 1、和方法引用一样的理解方法，你的get()方法没有参数，我的Employee()也没有参数。</span></span><br><span class="line"><span class="comment">     * 2、你的get()方法有返回值T，我的Employee()方法返回值也是一个对象</span></span><br><span class="line"><span class="comment">     * 3、所以刚好可以用  </span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">        Supplier&lt;Employee&gt; sup = <span class="keyword">new</span> Supplier&lt;Employee&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> Employee <span class="title">get</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">new</span> Employee();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Supplier&lt;Employee&gt;  sup1 = () -&gt; <span class="keyword">new</span> Employee();</span><br><span class="line">        System.out.println(sup1.get());</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Supplier&lt;Employee&gt;  sup2 = Employee :: <span class="keyword">new</span>;</span><br><span class="line">        System.out.println(sup2.get());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//Function中的R apply(T t)</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Function&lt;Integer,Employee&gt; func1 = id -&gt; <span class="keyword">new</span> Employee(id);</span><br><span class="line">        Employee employee = func1.apply(<span class="number">1001</span>);</span><br><span class="line">        System.out.println(employee);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Function&lt;Integer,Employee&gt; func2 = Employee :: <span class="keyword">new</span>;</span><br><span class="line">        Employee employee1 = func2.apply(<span class="number">1002</span>);</span><br><span class="line">        System.out.println(employee1);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//BiFunction中的R apply(T t,U u)</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span></span>&#123;</span><br><span class="line">        BiFunction&lt;Integer,String,Employee&gt; func1 = (id,name) -&gt; <span class="keyword">new</span> Employee(id,name);</span><br><span class="line">        System.out.println(func1.apply(<span class="number">1001</span>,<span class="string">&quot;Tom&quot;</span>));</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        BiFunction&lt;Integer,String,Employee&gt; func2 = Employee :: <span class="keyword">new</span>;</span><br><span class="line">        System.out.println(func2.apply(<span class="number">1002</span>,<span class="string">&quot;Tom&quot;</span>));</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//数组引用</span></span><br><span class="line">    <span class="comment">//Function中的R apply(T t)</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Function&lt;Integer,String[]&gt; func1 = length -&gt; <span class="keyword">new</span> String[length];</span><br><span class="line">        String[] arr1 = func1.apply(<span class="number">5</span>);</span><br><span class="line">        System.out.println(Arrays.toString(arr1));</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;*******************&quot;</span>);</span><br><span class="line"></span><br><span class="line">        Function&lt;Integer,String[]&gt; func2 = String[] :: <span class="keyword">new</span>;</span><br><span class="line">        String[] arr2 = func2.apply(<span class="number">10</span>);</span><br><span class="line">        System.out.println(Arrays.toString(arr2));</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h1 id="强大的Stream-API"><a href="#强大的Stream-API" class="headerlink" title="强大的Stream API"></a>强大的Stream API</h1><h2 id="Stream-API说明"><a href="#Stream-API说明" class="headerlink" title="Stream API说明"></a>Stream API说明</h2><ul>
<li><p>Java8中有两大最为重要的改变。第一个是 <strong>Lambda</strong> <strong>表达式</strong>；另外一个则是 <strong>Stream API</strong>。 </p>
</li>
<li><p>Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充，因为Stream API可以极大提供Java程序员的生产力，让程序员写出高效率、干净、简洁的代码。</p>
</li>
<li><p>Stream 是 Java8 中处理集合的关键抽象概念，它可以指定你希望对集合进行的操作，可以执行非常复杂的查找、过滤和映射数据等操作。 <strong>使用Stream API 对集合数据进行操作，就类似于使用 SQL 执行的数据库查询。</strong>也可以使用 Stream API 来并行执行操作。简言之，Stream API 提供了一种高效且易于使用的处理数据的方式</p>
</li>
</ul>
<h2 id="为什么要使用Stream-API"><a href="#为什么要使用Stream-API" class="headerlink" title="为什么要使用Stream API"></a>为什么要使用Stream API</h2><ul>
<li><p>实际开发中，项目中多数数据源都来自于Mysql，Oracle等，很多一些复杂的数据获取可以直接在sql层面去解决。但现在数据源可以更多了，有MongDB，Radis等，而这些NoSQL的数据本身不支持一些复杂的数据计算，这个时候就需要Java层面去处理。 </p>
</li>
<li><p>Stream 和 Collection 集合的区别：Collection 是一种静态的内存数据结构，而 Stream 是有关计算的。前者是主要面向内存，存储在内存中，后者主要是面向 CPU，通过 CPU 实现计算。</p>
</li>
</ul>
<h2 id="什么是Stream"><a href="#什么是Stream" class="headerlink" title="什么是Stream"></a>什么是Stream</h2><p>Stream到底是什么呢？</p>
<p>是数据渠道，用于操作数据源（集合、数组等）所生成的元素序列。</p>
<p><strong>“集合讲的是数据，Stream讲的是计算！”</strong></p>
<p><strong>注意：</strong></p>
<p>①Stream 自己不会存储元素。</p>
<p>②Stream 不会改变源对象。相反，他们会返回一个持有结果的新Stream。 </p>
<p>③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行</p>
<p><strong>Stream</strong> <strong>的操作三个步骤</strong></p>
<p>1、创建Stream</p>
<p>一个数据源（如：集合、数组），获取一个流</p>
<p>2、中间操作</p>
<p>一个中间操作链，对数据源的数据进行处理</p>
<p>3、终止操作(终端操作) </p>
<p>一旦执行终止操作，就执行中间操作链，才产生结果【也就是所谓的延迟执行】。之后，不会再被使用</p>
<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.8/Java_Basis/Java8_New_Features/0004.png">





<h2 id="创建Stream"><a href="#创建Stream" class="headerlink" title="创建Stream"></a>创建Stream</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StreamAPITest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//创建 Stream方式一：通过集合</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line"></span><br><span class="line"><span class="comment">//        default Stream&lt;E&gt; stream() : 返回一个顺序流，顺序流等会中间操作拿数据的时候按顺序拿</span></span><br><span class="line">        Stream&lt;Employee&gt; stream = employees.stream();</span><br><span class="line"></span><br><span class="line"><span class="comment">//        default Stream&lt;E&gt; parallelStream() : 返回一个并行流</span></span><br><span class="line">        Stream&lt;Employee&gt; parallelStream = employees.parallelStream();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//创建 Stream方式二：通过数组</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">int</span>[] arr = <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>&#125;;</span><br><span class="line">        <span class="comment">//调用Arrays类的static &lt;T&gt; Stream&lt;T&gt; stream(T[] array): 返回一个流</span></span><br><span class="line">        IntStream stream = Arrays.stream(arr);</span><br><span class="line"></span><br><span class="line">        Employee e1 = <span class="keyword">new</span> Employee(<span class="number">1001</span>,<span class="string">&quot;Tom&quot;</span>);</span><br><span class="line">        Employee e2 = <span class="keyword">new</span> Employee(<span class="number">1002</span>,<span class="string">&quot;Jerry&quot;</span>);</span><br><span class="line">        Employee[] arr1 = <span class="keyword">new</span> Employee[]&#123;e1,e2&#125;;</span><br><span class="line">        Stream&lt;Employee&gt; stream1 = Arrays.stream(arr1);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//创建 Stream方式三：通过Stream的of()，通过显示值创建一个流。它可以接收任意数量的参数</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">        Stream&lt;Integer&gt; stream = Stream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//创建 Stream方式四：创建无限流【用的少，了解下就行】</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">//      迭代</span></span><br><span class="line"><span class="comment">//      public static&lt;T&gt; Stream&lt;T&gt; iterate(final T seed, final UnaryOperator&lt;T&gt; f)</span></span><br><span class="line">        <span class="comment">//遍历前10个偶数</span></span><br><span class="line">        Stream.iterate(<span class="number">0</span>, t -&gt; t + <span class="number">2</span>).limit(<span class="number">10</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//      生成</span></span><br><span class="line"><span class="comment">//      public static&lt;T&gt; Stream&lt;T&gt; generate(Supplier&lt;T&gt; s)</span></span><br><span class="line">        Stream.generate(Math::random).limit(<span class="number">10</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>





<h2 id="中间操作"><a href="#中间操作" class="headerlink" title="中间操作"></a>中间操作</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 测试Stream的中间操作</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StreamAPITest1</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1-筛选与切片</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;Employee&gt; list = EmployeeData.getEmployees();</span><br><span class="line"><span class="comment">//        filter(Predicate p)——过滤   接收 Lambda ， 从流中排除某些元素。</span></span><br><span class="line">        Stream&lt;Employee&gt; stream = list.stream();</span><br><span class="line">        <span class="comment">//练习：查询员工表中薪资大于7000的员工信息</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * List&lt;String&gt; filterStrs1 = filterString(list,s -&gt; s.contains(&quot;京&quot;));</span></span><br><span class="line"><span class="comment">         * 跟之前的这个lambda表达式代码是一个意思</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        stream.filter(e -&gt; e.getSalary() &gt; <span class="number">7000</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        System.out.println();</span><br><span class="line"><span class="comment">//        limit(n)——截断流，使其元素不超过给定数量。</span></span><br><span class="line">        list.stream().limit(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">        System.out.println();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">        skip(n) —— 跳过元素，返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个，</span></span><br><span class="line"><span class="comment">        则返回一个空流。与 limit(n) 互补</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        list.stream().skip(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        System.out.println();</span><br><span class="line"><span class="comment">//        distinct()——筛选，通过流所生成元素的 hashCode() 和 equals() 去除重复元素</span></span><br><span class="line"></span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>,<span class="string">&quot;刘强东&quot;</span>,<span class="number">40</span>,<span class="number">8000</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>,<span class="string">&quot;刘强东&quot;</span>,<span class="number">41</span>,<span class="number">8000</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>,<span class="string">&quot;刘强东&quot;</span>,<span class="number">40</span>,<span class="number">8000</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>,<span class="string">&quot;刘强东&quot;</span>,<span class="number">40</span>,<span class="number">8000</span>));</span><br><span class="line">        list.add(<span class="keyword">new</span> Employee(<span class="number">1010</span>,<span class="string">&quot;刘强东&quot;</span>,<span class="number">40</span>,<span class="number">8000</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">//        System.out.println(list);</span></span><br><span class="line"></span><br><span class="line">        list.stream().distinct().forEach(System.out::println);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//映射</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">        map(Function f)——接收一个函数作为参数，将元素转换成其他形式或提取信息，该函数会被应</span></span><br><span class="line"><span class="comment">        用到每个元素上，并将其映射成一个新的元素。</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;aa&quot;</span>, <span class="string">&quot;bb&quot;</span>, <span class="string">&quot;cc&quot;</span>, <span class="string">&quot;dd&quot;</span>);</span><br><span class="line">        list.stream().map(str -&gt; str.toUpperCase()).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        练习1：获取员工姓名长度大于3的员工的姓名。</span></span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">        Stream&lt;String&gt; namesStream = employees.stream().map(Employee::getName);</span><br><span class="line">        namesStream.filter(name -&gt; name.length() &gt; <span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">        System.out.println();</span><br><span class="line">        <span class="comment">//练习2：</span></span><br><span class="line">        Stream&lt;Stream&lt;Character&gt;&gt; streamStream = list.stream().map(StreamAPITest1::fromStringToStream);</span><br><span class="line">        <span class="comment">//这个还需要两层遍历</span></span><br><span class="line">        streamStream.forEach(s -&gt;&#123;</span><br><span class="line">            s.forEach(System.out::println);</span><br><span class="line">        &#125;);</span><br><span class="line">        System.out.println();</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">        flatMap(Function f)——接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连</span></span><br><span class="line"><span class="comment">        接成一个流。flatMap一层遍历即可拿到想要的结果</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        Stream&lt;Character&gt; characterStream = list.stream().flatMap(StreamAPITest1::fromStringToStream);</span><br><span class="line">        characterStream.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//将字符串中的多个字符构成的集合转换为对应的Stream的实例</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Stream&lt;Character&gt; <span class="title">fromStringToStream</span><span class="params">(String str)</span></span>&#123;<span class="comment">//aa</span></span><br><span class="line">        ArrayList&lt;Character&gt; list = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span>(Character c : str.toCharArray())&#123;</span><br><span class="line">            list.add(c);</span><br><span class="line">        &#125;</span><br><span class="line">       <span class="keyword">return</span> list.stream();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">//3-排序</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="comment">//        sorted()——自然排序</span></span><br><span class="line">        List&lt;Integer&gt; list = Arrays.asList(<span class="number">12</span>, <span class="number">43</span>, <span class="number">65</span>, <span class="number">34</span>, <span class="number">87</span>, <span class="number">0</span>, -<span class="number">98</span>, <span class="number">7</span>);</span><br><span class="line">        list.stream().sorted().forEach(System.out::println);</span><br><span class="line">        <span class="comment">//抛异常，原因:Employee没有实现Comparable接口</span></span><br><span class="line"><span class="comment">//        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span></span><br><span class="line"><span class="comment">//        employees.stream().sorted().forEach(System.out::println);</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//        sorted(Comparator com)——定制排序</span></span><br><span class="line"></span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">        employees.stream().sorted( (e1,e2) -&gt; &#123;</span><br><span class="line"></span><br><span class="line">           <span class="keyword">int</span> ageValue = Integer.compare(e1.getAge(),e2.getAge());</span><br><span class="line">           <span class="keyword">if</span>(ageValue != <span class="number">0</span>)&#123;</span><br><span class="line">               <span class="keyword">return</span> ageValue;</span><br><span class="line">           &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">               <span class="keyword">return</span> -Double.compare(e1.getSalary(),e2.getSalary());</span><br><span class="line">           &#125;</span><br><span class="line"></span><br><span class="line">        &#125;).forEach(System.out::println);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h2 id="终止操作"><a href="#终止操作" class="headerlink" title="终止操作"></a>终止操作</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 测试Stream的终止操作</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StreamAPITest2</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//1-匹配与查找</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line"></span><br><span class="line"><span class="comment">//        allMatch(Predicate p)——检查是否匹配所有元素。</span></span><br><span class="line"><span class="comment">//          练习：是否所有的员工的年龄都大于18</span></span><br><span class="line">        <span class="keyword">boolean</span> allMatch = employees.stream().allMatch(e -&gt; e.getAge() &gt; <span class="number">18</span>);</span><br><span class="line">        System.out.println(allMatch);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        anyMatch(Predicate p)——检查是否至少匹配一个元素。</span></span><br><span class="line"><span class="comment">//         练习：是否存在员工的工资大于 10000</span></span><br><span class="line">        <span class="keyword">boolean</span> anyMatch = employees.stream().anyMatch(e -&gt; e.getSalary() &gt; <span class="number">10000</span>);</span><br><span class="line">        System.out.println(anyMatch);</span><br><span class="line"></span><br><span class="line"><span class="comment">//        noneMatch(Predicate p)——检查是否没有匹配的元素。</span></span><br><span class="line"><span class="comment">//          练习：是否存在员工姓“雷”</span></span><br><span class="line">        <span class="keyword">boolean</span> noneMatch = employees.stream().noneMatch(e -&gt; e.getName().startsWith(<span class="string">&quot;雷&quot;</span>));</span><br><span class="line">        System.out.println(noneMatch);</span><br><span class="line"><span class="comment">//        findFirst——返回第一个元素</span></span><br><span class="line">        Optional&lt;Employee&gt; employee = employees.stream().findFirst();</span><br><span class="line">        System.out.println(employee);</span><br><span class="line"><span class="comment">//        findAny——返回当前流中的任意元素</span></span><br><span class="line">        Optional&lt;Employee&gt; employee1 = employees.parallelStream().findAny();</span><br><span class="line">        System.out.println(employee1);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">        <span class="comment">// count——返回流中元素的总个数</span></span><br><span class="line">        <span class="keyword">long</span> count = employees.stream().filter(e -&gt; e.getSalary() &gt; <span class="number">5000</span>).count();</span><br><span class="line">        System.out.println(count);</span><br><span class="line"><span class="comment">//        max(Comparator c)——返回流中最大值</span></span><br><span class="line"><span class="comment">//        练习：返回最高的工资：</span></span><br><span class="line">        Stream&lt;Double&gt; salaryStream = employees.stream().map(e -&gt; e.getSalary());</span><br><span class="line">        Optional&lt;Double&gt; maxSalary = salaryStream.max(Double::compare);</span><br><span class="line">        System.out.println(maxSalary);</span><br><span class="line"><span class="comment">//        min(Comparator c)——返回流中最小值</span></span><br><span class="line"><span class="comment">//        练习：返回最低工资的员工</span></span><br><span class="line">        Optional&lt;Employee&gt; employee = employees.stream().min((e1, e2) -&gt; Double.compare(e1.getSalary(), e2.getSalary()));</span><br><span class="line">        System.out.println(employee);</span><br><span class="line">        System.out.println();</span><br><span class="line"><span class="comment">//        forEach(Consumer c)——内部迭代</span></span><br><span class="line">        employees.stream().forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//使用集合的遍历操作</span></span><br><span class="line">        employees.forEach(System.out::println);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//2-归约</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="comment">//        reduce(T identity, BinaryOperator)——可以将流中元素反复结合起来，得到一个值。返回 T</span></span><br><span class="line"><span class="comment">//        练习1：计算1-10的自然数的和</span></span><br><span class="line">        List&lt;Integer&gt; list = Arrays.asList(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>);</span><br><span class="line">        Integer sum = list.stream().reduce(<span class="number">0</span>, Integer::sum);</span><br><span class="line">        System.out.println(sum);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//        reduce(BinaryOperator) ——可以将流中元素反复结合起来，得到一个值。返回 Optional&lt;T&gt;</span></span><br><span class="line"><span class="comment">//        练习2：计算公司所有员工工资的总和</span></span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">        Stream&lt;Double&gt; salaryStream = employees.stream().map(Employee::getSalary);</span><br><span class="line"><span class="comment">//        Optional&lt;Double&gt; sumMoney = salaryStream.reduce(Double::sum);</span></span><br><span class="line">        Optional&lt;Double&gt; sumMoney = salaryStream.reduce((d1,d2) -&gt; d1 + d2);</span><br><span class="line">        System.out.println(sumMoney.get());</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//3-收集</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="comment">// collect(Collector c)——将流转换为其他形式。接收一个 Collector接口的实现，用于给Stream中元素做汇总的方法</span></span><br><span class="line"><span class="comment">//        练习1：查找工资大于6000的员工，结果返回为一个List或Set</span></span><br><span class="line"></span><br><span class="line">        List&lt;Employee&gt; employees = EmployeeData.getEmployees();</span><br><span class="line">        List&lt;Employee&gt; employeeList = employees.stream().filter(e -&gt; e.getSalary() &gt; <span class="number">6000</span>).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line">        employeeList.forEach(System.out::println);</span><br><span class="line">        System.out.println();</span><br><span class="line">        Set&lt;Employee&gt; employeeSet = employees.stream().filter(e -&gt; e.getSalary() &gt; <span class="number">6000</span>).collect(Collectors.toSet());</span><br><span class="line"></span><br><span class="line">        employeeSet.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h1 id="Optional类"><a href="#Optional类" class="headerlink" title="Optional类"></a>Optional类</h1><h2 id="什么是Optional？"><a href="#什么是Optional？" class="headerlink" title="什么是Optional？"></a>什么是Optional？</h2><ul>
<li><p>到目前为止，臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前，为了解决空指针异常，Google公司著名的Guava项目引入了Optional类，Guava通过使用检查空值的方式来防止代码污染，它鼓励程序员写更干净的代码。受到Google Guava的启发，Optional类已经成为Java 8类库的一部分。</p>
</li>
<li><p>Optional<T> 类(java.util.Optional) 是一个容器类，它可以保存类型T的值，代表这个值存在。或者仅仅保存null，表示这个值不存在。原来用 null 表示一个值不存在，现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。 </p>
</li>
<li><p>Optional类的Javadoc描述如下：这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true，调用get()方法会返回该对象。</p>
</li>
</ul>
<h2 id="常用API"><a href="#常用API" class="headerlink" title="常用API"></a>常用API</h2><img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.8/Java_Basis/Java8_New_Features/0005.png">





<h2 id="举例"><a href="#举例" class="headerlink" title="举例"></a>举例</h2><p>首先准备两个类</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Boy</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Girl girl;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Boy&#123;&quot;</span> +</span><br><span class="line">                <span class="string">&quot;girl=&quot;</span> + girl +</span><br><span class="line">                <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Girl <span class="title">getGirl</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> girl;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setGirl</span><span class="params">(Girl girl)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.girl = girl;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Boy</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Boy</span><span class="params">(Girl girl)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.girl = girl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Girl</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Girl&#123;&quot;</span> +</span><br><span class="line">                <span class="string">&quot;name=&#x27;&quot;</span> + name + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Girl</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Girl</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>这里只是简单的测试两个API</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Optional类：为了在程序中避免出现空指针异常而创建的。</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 常用的方法：ofNullable(T t)</span></span><br><span class="line"><span class="comment"> *            orElse(T t)</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OptionalTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Optional.of(T t) : 创建一个 Optional 实例，t必须非空；</span></span><br><span class="line"><span class="comment">Optional.empty() : 创建一个空的 Optional 实例</span></span><br><span class="line"><span class="comment">Optional.ofNullable(T t)：t可以为null</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Girl girl = <span class="keyword">new</span> Girl();</span><br><span class="line"><span class="comment">//        girl = null;</span></span><br><span class="line">        <span class="comment">//of(T t):保证t是非空的</span></span><br><span class="line">        Optional&lt;Girl&gt; optionalGirl = Optional.of(girl);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Girl girl = <span class="keyword">new</span> Girl();</span><br><span class="line"><span class="comment">//        girl = null;</span></span><br><span class="line">        <span class="comment">//ofNullable(T t)：t可以为null</span></span><br><span class="line">        Optional&lt;Girl&gt; optionalGirl = Optional.ofNullable(girl);</span><br><span class="line">        System.out.println(optionalGirl);</span><br><span class="line">        <span class="comment">//orElse(T t1):如果单前的Optional内部封装的t是非空的，则返回内部的t.</span></span><br><span class="line">        <span class="comment">//如果内部的t是空的，则返回orElse()方法中的参数t1.</span></span><br><span class="line">        Girl girl1 = optionalGirl.orElse(<span class="keyword">new</span> Girl(<span class="string">&quot;赵丽颖&quot;</span>));</span><br><span class="line">        System.out.println(girl1);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p><strong>实际场景使用</strong></p>
<p>可能出现空指针的例子：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">getGirlName</span><span class="params">(Boy boy)</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> boy.getGirl().getName();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test3</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Boy boy = <span class="keyword">new</span> Boy();</span><br><span class="line">        boy = <span class="keyword">null</span>;</span><br><span class="line">        String girlName = getGirlName(boy);</span><br><span class="line">        System.out.println(girlName);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>



<p>结果：</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">java.lang.NullPointerException</span><br><span class="line">	at com.atguigu.java4.OptionalTest.getGirlName(OptionalTest.java:47)</span><br><span class="line">	at com.atguigu.java4.OptionalTest.test3(OptionalTest.java:54)</span><br><span class="line">...</span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">Process finished with exit code -1</span><br></pre></td></tr></table></figure>



<p>没有Optional的解决办法，但是如果调用层数过多，就得一层一层判断是否为null，写起来很麻烦。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//优化以后的getGirlName():</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getGirlName1</span><span class="params">(Boy boy)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(boy != <span class="keyword">null</span>)&#123;</span><br><span class="line">            Girl girl = boy.getGirl();</span><br><span class="line">            <span class="keyword">if</span>(girl != <span class="keyword">null</span>)&#123;</span><br><span class="line">                <span class="keyword">return</span> girl.getName();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test4</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Boy boy = <span class="keyword">new</span> Boy();</span><br><span class="line">        boy = <span class="keyword">null</span>;</span><br><span class="line">        String girlName = getGirlName1(boy);</span><br><span class="line">        System.out.println(girlName);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>



<p>使用Optional解决问题：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//使用Optional类的getGirlName():</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> String <span class="title">getGirlName2</span><span class="params">(Boy boy)</span></span>&#123;</span><br><span class="line"></span><br><span class="line">       Optional&lt;Boy&gt; boyOptional = Optional.ofNullable(boy);</span><br><span class="line">       <span class="comment">//此时的boy1一定非空</span></span><br><span class="line">       Boy boy1 = boyOptional.orElse(<span class="keyword">new</span> Boy(<span class="keyword">new</span> Girl(<span class="string">&quot;迪丽热巴&quot;</span>)));</span><br><span class="line"></span><br><span class="line">       Girl girl = boy1.getGirl();</span><br><span class="line"></span><br><span class="line">       Optional&lt;Girl&gt; girlOptional = Optional.ofNullable(girl);</span><br><span class="line">       <span class="comment">//girl1一定非空</span></span><br><span class="line">       Girl girl1 = girlOptional.orElse(<span class="keyword">new</span> Girl(<span class="string">&quot;古力娜扎&quot;</span>));</span><br><span class="line"></span><br><span class="line">       <span class="keyword">return</span> girl1.getName();</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@Test</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test5</span><span class="params">()</span></span>&#123;</span><br><span class="line">       Boy boy = <span class="keyword">null</span>;</span><br><span class="line">       boy = <span class="keyword">new</span> Boy();</span><br><span class="line">       boy = <span class="keyword">new</span> Boy(<span class="keyword">new</span> Girl(<span class="string">&quot;苍老师&quot;</span>));</span><br><span class="line">       String girlName = getGirlName2(boy);</span><br><span class="line">       System.out.println(girlName);</span><br><span class="line"></span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>

<p>这种是绝对不会出现空指针的。</p>
<h1 id="接口的增强"><a href="#接口的增强" class="headerlink" title="接口的增强"></a>接口的增强</h1><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">JDK7及以前：只能定义全局常量和抽象方法</span><br><span class="line">  &gt;全局常量：public static final的.但是书写时，可以省略不写</span><br><span class="line">  &gt;抽象方法：public abstract的</span><br><span class="line">  			</span><br><span class="line">JDK8：除了定义全局常量和抽象方法之外，还可以定义静态方法、默认方法</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * JDK8：除了定义全局常量和抽象方法之外，还可以定义静态方法、默认方法</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CompareA</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//静态方法</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">method1</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;CompareA:北京&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//默认方法</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">default</span> <span class="keyword">void</span> <span class="title">method2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;CompareA：上海&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//接口中的public 可以省略，自动就是public</span></span><br><span class="line">    <span class="function"><span class="keyword">default</span> <span class="keyword">void</span> <span class="title">method3</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;CompareA：上海&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SuperClass</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method3</span><span class="params">()</span></span>&#123;</span><br><span class="line">		System.out.println(<span class="string">&quot;SuperClass:北京&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CompareB</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">default</span> <span class="keyword">void</span> <span class="title">method3</span><span class="params">()</span></span>&#123;</span><br><span class="line">		System.out.println(<span class="string">&quot;CompareB：上海&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SubClassTest</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SubClass s = <span class="keyword">new</span> SubClass();</span><br><span class="line">		</span><br><span class="line"><span class="comment">//		s.method1();</span></span><br><span class="line"><span class="comment">//		SubClass.method1();</span></span><br><span class="line">		<span class="comment">//知识点1：接口中定义的静态方法，只能通过接口来调用。实现类用不了</span></span><br><span class="line">		CompareA.method1();</span><br><span class="line">		<span class="comment">//知识点2：通过实现类的对象，可以调用接口中的默认方法。</span></span><br><span class="line">		<span class="comment">//如果实现类重写了接口中的默认方法，调用时，仍然调用的是重写以后的方法</span></span><br><span class="line">		s.method2();</span><br><span class="line">		<span class="comment">//知识点3：如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法，</span></span><br><span class="line">		<span class="comment">//那么子类在没有重写此方法的情况下，默认调用的是父类中的同名同参数的方法。--&gt;类优先原则</span></span><br><span class="line">		<span class="comment">//知识点4：如果实现类实现了多个接口，而这多个接口中定义了同名同参数的默认方法，</span></span><br><span class="line">		<span class="comment">//那么在实现类没有重写此方法的情况下，报错。--&gt;接口冲突。</span></span><br><span class="line">		<span class="comment">//这就需要我们必须在实现类中重写此方法</span></span><br><span class="line">		s.method3();</span><br><span class="line">		</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SubClass</span> <span class="keyword">extends</span> <span class="title">SuperClass</span> <span class="keyword">implements</span> <span class="title">CompareA</span>,<span class="title">CompareB</span></span>&#123;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method2</span><span class="params">()</span></span>&#123;</span><br><span class="line">		System.out.println(<span class="string">&quot;SubClass：上海&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method3</span><span class="params">()</span></span>&#123;</span><br><span class="line">		System.out.println(<span class="string">&quot;SubClass：深圳&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="comment">//知识点5：如何在子类(或实现类)的方法中调用父类、接口中被重写的方法</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">myMethod</span><span class="params">()</span></span>&#123;</span><br><span class="line">		method3();<span class="comment">//调用自己定义的重写的方法</span></span><br><span class="line">		<span class="keyword">super</span>.method3();<span class="comment">//调用的是父类中声明的</span></span><br><span class="line">		<span class="comment">//调用接口中的默认方法</span></span><br><span class="line">		CompareA.<span class="keyword">super</span>.method3();</span><br><span class="line">		CompareB.<span class="keyword">super</span>.method3();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<h1 id="日期API【TODO】"><a href="#日期API【TODO】" class="headerlink" title="日期API【TODO】"></a>日期API【TODO】</h1><h1 id="注解【TODO】"><a href="#注解【TODO】" class="headerlink" title="注解【TODO】"></a>注解【TODO】</h1></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">youthlql</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://imlql.cn/post/de3879ae.html">https://imlql.cn/post/de3879ae.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://imlql.cn" target="_blank">风祈的时光录</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Java8/">Java8</a><a class="post-meta__tags" href="/tags/JDK8/">JDK8</a><a class="post-meta__tags" href="/tags/%E6%96%B0%E7%89%B9%E6%80%A7/">新特性</a></div><div class="post_share"></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://npm.elemecdn.com/youthlql@1.0.8/blog/wechat.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://npm.elemecdn.com/youthlql@1.0.8/blog/wechat.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://npm.elemecdn.com/youthlql@1.0.8/blog/alipay.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://npm.elemecdn.com/youthlql@1.0.8/blog/alipay.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/post/adb2faf0.html"><img class="prev-cover" src= "" data-lazy-src="https://upyunimg.imlql.cn/lql_static@latest/logo/java.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">万字长文详解Java泛型</div></div></a></div><div class="next-post pull-right"><a href="/post/70c90e5d.html"><img class="next-cover" src= "" data-lazy-src="https://upyunimg.imlql.cn/lql_static@latest/logo/Java_concurrency.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Java并发体系-第三阶段-JUC并发包-[2]</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Java8%E6%96%B0%E7%89%B9%E6%80%A7%E7%BA%B5%E8%A7%88"><span class="toc-text">Java8新特性纵览</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F"><span class="toc-text">Lambda表达式</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%BF%E7%94%A8Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F%EF%BC%9F"><span class="toc-text">为什么使用Lambda表达式？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8"><span class="toc-text">简单使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Lambda%E8%AF%AD%E6%B3%95%E8%A7%84%E5%88%99"><span class="toc-text">Lambda语法规则</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BC%8F%E6%8E%A5%E5%8F%A3"><span class="toc-text">函数式接口</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E5%87%BD%E6%95%B0%E5%BC%8F-Functional-%E6%8E%A5%E5%8F%A3"><span class="toc-text">什么是函数式(Functional)接口</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3%E5%87%BD%E6%95%B0%E5%BC%8F%E6%8E%A5%E5%8F%A3"><span class="toc-text">如何理解函数式接口</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Java%E5%86%85%E7%BD%AE%E5%87%BD%E6%95%B0%E5%BC%8F%E6%8E%A5%E5%8F%A3"><span class="toc-text">Java内置函数式接口</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0%E5%BC%8F%E6%8E%A5%E5%8F%A3"><span class="toc-text">自定义函数式接口</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E5%BC%95%E7%94%A8"><span class="toc-text">方法引用</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%9E%84%E9%80%A0%E5%99%A8%E5%BC%95%E7%94%A8"><span class="toc-text">构造器引用</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%BC%BA%E5%A4%A7%E7%9A%84Stream-API"><span class="toc-text">强大的Stream API</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Stream-API%E8%AF%B4%E6%98%8E"><span class="toc-text">Stream API说明</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8Stream-API"><span class="toc-text">为什么要使用Stream API</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AFStream"><span class="toc-text">什么是Stream</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%9B%E5%BB%BAStream"><span class="toc-text">创建Stream</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%AD%E9%97%B4%E6%93%8D%E4%BD%9C"><span class="toc-text">中间操作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%88%E6%AD%A2%E6%93%8D%E4%BD%9C"><span class="toc-text">终止操作</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Optional%E7%B1%BB"><span class="toc-text">Optional类</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AFOptional%EF%BC%9F"><span class="toc-text">什么是Optional？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B8%B8%E7%94%A8API"><span class="toc-text">常用API</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BE%E4%BE%8B"><span class="toc-text">举例</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%A2%9E%E5%BC%BA"><span class="toc-text">接口的增强</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%97%A5%E6%9C%9FAPI%E3%80%90TODO%E3%80%91"><span class="toc-text">日期API【TODO】</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%B3%A8%E8%A7%A3%E3%80%90TODO%E3%80%91"><span class="toc-text">注解【TODO】</span></a></li></ol></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By youthlql</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text"><a href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral" target="_blank" rel="noopener" class="one-pan-link-mark"><img style="position:relative;top:-3px; " src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/upyun/logo.png" align="absmiddle" width="60px" height="30px"></a><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn"><img class="icp-icon" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/icp.png"><span>鄂ICP备19028890号</span></a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">简</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">本地搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://npm.elemecdn.com/@fancyapps/ui/dist/fancybox.umd.js"></script><script src="https://npm.elemecdn.com/instant.page/instantpage.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"></div><script defer src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script></div></body></html>